package com.hsnn.medstgmini.base.dict.dao.impl;


import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.Transformers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.hsnn.medstgmini.base.dict.dao.DicHosptypeDao;
import com.hsnn.medstgmini.base.dict.model.DicHosptype;
import com.hsnn.medstgmini.dao.impl.HibernateSqlUtilImpl;
import com.hsnn.medstgmini.util.Pagination;


@Repository("DicHosptypeDao")
public class DicHosptypeDaoImpl extends BaseHibernateDAO implements DicHosptypeDao {
	
	@Resource(name = "sessionFactory")
	private SessionFactory factory;
	
	@Resource(name = "sessionFactory")
	private SessionFactory sessionFactory;
	
	private static final Logger log = LoggerFactory
			.getLogger(DicHosptypeDaoImpl.class);
	// property constants
	public static final String HOSP_TYPE_CODE = "hospTypeCode";
	public static final String HOSP_TYPE = "hospType";
	public static final String FATHER_ID = "fatherId";
	public static final String STATUS = "status";
	public static final String UPD_USER = "updUser";
	public static final String SORT_ID = "sortId";
	
	@Autowired
	private HibernateSqlUtilImpl dao;

	

	public DicHosptype findById(java.lang.String id) {
		if (log.isDebugEnabled()) {
			log.debug("getting DicHosptype instance with id: " + id);
		}
		try {
			DicHosptype instance = (DicHosptype) getSession().get(
					"com.hsnn.medstgmini.base.dict.model.DicHosptype", id);
			return instance;
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		}
	}
	
	
	
	@SuppressWarnings("unchecked")
	@Override
	public List<DicHosptype> getChildList(String Far) {
		if (log.isDebugEnabled()) {
			log.debug("finding Farther DicHosptype instance by Result and example");
		}
		try {
			
			Criteria c= getSession().createCriteria("com.hsnn.medstgmini.base.dict.model.DicHosptype");
				if(Far==null){
					c.add(Restrictions.eq("fatherId","0"));
					c.add(Restrictions.eq("status", Short.valueOf("1")));
				}else{	
					c.add(Restrictions.eq("fatherId",Far));
					c.add(Restrictions.eq("status",  Short.valueOf("1")));
				}
				List<DicHosptype> results=(List<DicHosptype>)c.addOrder(Order.asc("hospTypeCode")).list();
				if (log.isDebugEnabled()) {
					log.debug("find by example successful, result size: "
							+ results.size());
				}
			return results;
		} catch (RuntimeException re) {
			log.error("find by example failed", re);
			throw re;
		}
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<DicHosptype> getQYChildList(String Far) {
		if (log.isDebugEnabled()) {
			log.debug("finding Farther DicHosptype instance by Result and example");
		}
		try {
			Criteria c= getSession().createCriteria("com.hsnn.medstgmini.base.dict.model.DicHosptype");
				c.add(Restrictions.eq("fatherId",Far==null?"0":Far));
				List<DicHosptype> results=(List<DicHosptype>)c.add(Restrictions.eq("status", new Short("1"))).addOrder(Order.asc("hospTypeCode")).list();
				if (log.isDebugEnabled()) {
					log.debug("find by example successful, result size: "
							+ results.size());
				}
			return results;
		} catch (RuntimeException re) {
			log.error("find by example failed", re);
			throw re;
		}
	}

	
	@Override
	public Pagination getDicHospTypeList(Pagination page){
		Session session = getSession();
		String hospTypeCode = page.getConditions().get("hospTypeCode");
		String hospType = page.getConditions().get("hospType");
		String status = page.getConditions().get("status");
		StringBuffer sql = new StringBuffer();
		sql.append(" SELECT SQL_CALC_FOUND_ROWS * FROM                                ")
		   .append(" (SELECT b.hosp_type_id hospTypeId,                               ")
		   .append(" a.hosp_type_code fatherHospTypeCode,                             ")
		   .append(" a.hosp_type fatherHospType,b.hosp_type_code hospTypeCode,        ")
		   .append(" b.hosp_type hospType,b.status status							  ")
		   .append(" FROM dic_hosptype a                                         	  ")
		   .append(" INNER JOIN dic_hosptype b  ON b.father_id=a.hosp_type_id         ")
		   .append(" WHERE a.father_id = '0'										  ")
		   .append(" UNION															  ")
		   .append(" SELECT hosp_type_id,hosp_type_code,hosp_type,NULL,NULL,STATUS    ")
		   .append(" FROM dic_hosptype WHERE father_id = '0')t WHERE 1=1			  ");
		if(StringUtils.isNotBlank(hospTypeCode)){
			sql.append(" and (t.fatherHospTypeCode = :hospTypeCode or t.hospTypeCode = :hospTypeCode ) ");
		}
		if(StringUtils.isNotBlank(hospType)){
			sql.append(" and (t.fatherHospType like :hospType or t.hospType like :hospType ) ");
		}
		if (StringUtils.isNotBlank(status)) {
			sql.append(" and (t.status = :status )");
		}
		sql.append(" ORDER BY t.fatherHospTypeCode,t.hospTypeCode ");
		Query query = session.createSQLQuery(sql.toString());
		Query queryCount = session.createSQLQuery(" select found_rows() ");
		if(StringUtils.isNotBlank(hospTypeCode)){
			query.setString("hospTypeCode", hospTypeCode);
		}
		if(StringUtils.isNotBlank(hospType)){
			query.setString("hospType", '%'+hospType+'%');
		}
		if(StringUtils.isNotBlank(status)){
			query.setString("status", status);
		}
		query.setFirstResult(page.getFirstResult());
		query.setMaxResults(page.getMaxResults());
		query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		page.setRows(query.list());
		page.setRecords(Long.parseLong(queryCount.uniqueResult().toString()));
		return page;
	}
	
	@Override
	public Pagination getDicHospTypeLogList(Pagination page){
		Session session = getSession();
		String hospTypeId=page.getConditions().get("hospTypeId");
		String startTime = page.getConditions().get("startTime");
		String endTime = page.getConditions().get("endTime");
		StringBuffer sql = new StringBuffer();
		sql.append("	SELECT SQL_CALC_FOUND_ROWS										")
		   .append("	b.hosp_type_code fatherCode,b.hosp_type fatherType,a.hosp_type_code code,    ")
		   .append("	a.hosp_type type,a.status,c.name,date_format(a.upd_datetime,'%Y-%m-%d %H:%i:%S'),   ")
		   .append("	 a.log_id logId,a.detail  FROM dic_hosptype_log a  										")
		   .append("	LEFT JOIN  dic_hosptype b ON b.hosp_type_id = a.father_id 		")
		   .append("	LEFT JOIN  sys_user c     ON c.id = a.upd_user					")
		   .append("	WHERE a.hosp_type_id = :hospTypeId								");
		if(StringUtils.isNotBlank(startTime)){
			sql.append("  and a.upd_datetime >= :startTime ");
		}  
		if(StringUtils.isNotBlank(endTime)){
			sql.append("  and a.upd_datetime <= :endTime ");
		}
		sql.append(" order by a.upd_datetime desc ");
		Query query = session.createSQLQuery(sql.toString());
		Query queryCount = session.createSQLQuery(" select found_rows() ");
		query.setString("hospTypeId", hospTypeId);
		if(StringUtils.isNotBlank(startTime)){
			query.setString("startTime", startTime+" 00:00:00");
		}  
		if(StringUtils.isNotBlank(endTime)){
			query.setString("endTime", endTime+" 23:59:59");
		}
		query.setFirstResult(page.getFirstResult());
		query.setMaxResults(page.getMaxResults());
		page.setRows(query.list());
		page.setRecords(Long.parseLong(queryCount.uniqueResult().toString()));
		return page;
	}
	
	/**
	 * 基础库 数据字典 医疗机构类别字典 根据id查询 医疗机构类别 日志详情
	 * @param page
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<Map<String, Object>> getDicHosptypeLogDetail(Pagination page) {
		Session session = sessionFactory.getCurrentSession();
		String logId = page.getConditions().get("logId");
		StringBuffer  sql = new StringBuffer();
		sql.append(" SELECT b.hosp_type_code fatherCode,b.hosp_type fatherType,a.hosp_type_code code,a.hosp_type type,a.status,c.name updUser, ")
		   .append(" date_format(a.upd_datetime,'%Y-%m-%d %H:%i:%S') updDatetime  FROM dic_hosptype_log a  ")
		   .append(" LEFT JOIN  dic_hosptype b ON b.hosp_type_id = a.father_id LEFT JOIN  sys_user c ON c.id = a.upd_user ")
		   .append(" WHERE a.hosp_type_id = (SELECT hosp_type_id FROM dic_hosptype_log WHERE log_id = :logId)    ")
		   .append(" AND a.upd_datetime <= (SELECT upd_datetime FROM dic_hosptype_log where log_id = :logId)  ")
		   .append(" order by a.upd_datetime desc limit 2 ");
		Query query = session.createSQLQuery(sql.toString());
		query.setString("logId", logId);
		query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		return query.list();
	}
	
	
	
	/**
	 * 
	 *@category 启用和停用
	 *@author wangbing
	 *@date 2015年6月9日
	 *Pagination
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void changeStatus(DicHosptype dicHosptype) {
		Session session = getSession();
		List<String> list = new ArrayList<String>();
		if("0".equals(dicHosptype.getStatus()+"")){
			StringBuffer sb = new StringBuffer()
			.append("select hosp_type_id from dic_hosptype where hosp_type_id= :hospTypeId or (father_id=:hospTypeId and status <> 0) ");
			Query query = session.createSQLQuery(sb.toString());
			query.setString("hospTypeId", dicHosptype.getHospTypeId());
			List<Object> data = query.list();
			for(int i = 0;i<data.size();i++){
				list.add(data.get(i).toString());
			}
		}
		StringBuffer sql = new StringBuffer();
		sql.append("update dic_hosptype  set ")
		  .append(" status=:status,upd_datetime=:updDatetime,upd_user=:updUser ")
		  .append(" where hosp_type_id= :hospTypeId ");
		if("0".equals(dicHosptype.getStatus()+"")){
			sql.append(" or (father_id=:hospTypeId and status <> 0)");
		}
		Query update = session.createSQLQuery(sql.toString());
		update.setLong("status",dicHosptype.getStatus());
		update.setTimestamp("updDatetime", new Date());
		update.setString("updUser", dicHosptype.getUpdUser());
		update.setString("hospTypeId", dicHosptype.getHospTypeId());
		update.executeUpdate();
		session.flush();
		writeLog(dicHosptype,list);
	}
	/**
	 * 
	 *@category 写日志
	 *@author wangbing
	 *@date 2015年6月9日
	 *Pagination
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void writeLog(DicHosptype dicHosptype,List<String> idList){
		Session session = getSession();
		StringBuffer detail = new StringBuffer();
		if(!"0".equals(dicHosptype.getStatus()+"")){
			StringBuffer sb = new StringBuffer()
			.append("select hosp_type_code HospTypeCode,hosp_type hospType,status from dic_hosptype where hosp_type_id= :hospTypeId ")
			.append(" UNION all ")
			.append(" select t.* from (select hosp_type_code HospTypeCode,hosp_type hospType,status from dic_hosptype_log where hosp_type_id= :hospTypeId order by upd_datetime desc limit 1) t");
			Query query1 = session.createSQLQuery(sb.toString());
			query1.setString("hospTypeId",dicHosptype.getHospTypeId());
			query1.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
			List<Map<String,Object>> list = query1.list();
			
			if(list.size()==1){
				detail.append("新增数据<br/>编码：")
			      .append(list.get(0).get("HospTypeCode").toString())
			      .append("<br/>名称：")
			      .append(list.get(0).get("hospType").toString());
			}else{
				if(!list.get(0).get("HospTypeCode").toString().equals(list.get(1).get("HospTypeCode").toString())){
					detail.append("编码由")
					      .append(list.get(1).get("HospTypeCode").toString())
					      .append("变为")
					      .append(list.get(0).get("HospTypeCode").toString());
				}
				if(!list.get(0).get("hospType").toString().equals(list.get(1).get("hospType").toString())){
					detail.append("<br/>名称由")
					      .append(list.get(1).get("hospType").toString())
					      .append("变为")
					      .append(list.get(0).get("hospType").toString());
				}
				if(!list.get(0).get("status").toString().equals(list.get(1).get("status").toString())){
					detail.append("<br/>状态由")
					      .append("1".equals(list.get(1).get("status").toString())?"启用":"停用")
					      .append("变为")
					      .append("1".equals(list.get(0).get("status").toString())?"启用":"停用");
				}
				if(detail.indexOf("<br/>")==0){
					detail.delete(0, 5);
				}
			}
			
		}
		
		StringBuffer sql = new StringBuffer();
		sql.append("insert into dic_hosptype_log(log_id,hosp_type_id,hosp_type_code,hosp_type,  ")
		   .append("father_id,status,upd_datetime,upd_user,sort_id,detail) select ")
		   .append(" UUID(),t.*,:detail from dic_hosptype t where t.hosp_type_id= :hospTypeId ");
		if("0".equals(dicHosptype.getStatus()+"")){
			sql.append(" or t.hosp_type_id in (:idList)");
			detail.append("状态由启用变为停用");
		}
		Query query=session.createSQLQuery(sql.toString());
		query.setString("hospTypeId",dicHosptype.getHospTypeId());
		query.setString("detail",detail.toString());
		if("0".equals(dicHosptype.getStatus()+"")){
			query.setParameterList("idList", idList);
		}
		query.executeUpdate();
		session.flush();
		
	}
	
	@Override
	public Pagination initEdit(Pagination page){
		String hospTypeId = page.getConditions().get("hospTypeId");
		Session session = getSession();
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT b.hosp_type_code fatherHospTypeCode,b.hosp_type fatherHospType,a.hosp_type_code hospTypeCode,a.hosp_type  hospType FROM dic_hosptype a ")
		   .append(" LEFT JOIN dic_hosptype b ON a.father_id = b.hosp_type_id WHERE a.hosp_type_id =:hospTypeId ");
		Query query=session.createSQLQuery(sql.toString());
		query.setString("hospTypeId",hospTypeId);
		page.setRows(query.uniqueResult());
		return page;
	}
	/**
	 * 编辑
	 */
	@Override
	public void updateHospType(Pagination page) {
		Session session = getSession();
		String hospTypeCode = page.getConditions().get("hospTypeCode");
		String hospType = page.getConditions().get("hospType");
		String hospTypeId = page.getConditions().get("hospTypeId");
		String updUser = page.getConditions().get("updUser");
		StringBuffer sql = new StringBuffer();
		sql.append(" update dic_hosptype set hosp_type_code=:hospTypeCode, ")
		   .append("hosp_type=:hospType,upd_datetime=:updDatetime,")
		   .append(" upd_user=:updUser where hosp_type_id=:hospTypeId      ");
		Query query = session.createSQLQuery(sql.toString());
		query.setString("hospTypeCode",hospTypeCode );
		query.setString("hospType",hospType );
		query.setString("updUser",updUser );
		query.setTimestamp("updDatetime", new Date());
		query.setString("hospTypeId", hospTypeId);
		query.executeUpdate();
		session.flush();
		DicHosptype dicHosptype = new DicHosptype();
		dicHosptype.setStatus((short)1);
		dicHosptype.setHospTypeId(hospTypeId);
		writeLog(dicHosptype,null);
	}
	/**
	 * 新增
	 */
	@Override
	public void addHospType(Pagination page) {
		Session session = getSession();
		String hospTypeCode = page.getConditions().get("hospTypeCode");
		String hospType = page.getConditions().get("hospType");
		String updUser = page.getConditions().get("updUser");
		String fatherId = page.getConditions().get("fatherId");
		String hospTypeId = page.getConditions().get("hospTypeAddId");
		StringBuffer sql = new StringBuffer();
		sql.append("insert into dic_hosptype(hosp_type_id,hosp_type_code,hosp_type,father_id,  ")
		   .append("status,upd_datetime,upd_user) values ( ")
		   .append(":hospTypeId,:hospTypeCode,:hospType,:fatherId,1,:updDatetime,:updUser) ");
		Query query = session.createSQLQuery(sql.toString());
		query.setString("hospTypeCode",hospTypeCode );
		query.setString("hospType",hospType );
		query.setString("updUser",updUser );
		query.setTimestamp("updDatetime", new Date());
		query.setString("fatherId", fatherId);
		query.setString("hospTypeId", hospTypeId);
		query.executeUpdate();
		session.flush();
		DicHosptype dicHosptype = new DicHosptype();
		dicHosptype.setStatus((short)1);
		dicHosptype.setHospTypeId(hospTypeId);
		writeLog(dicHosptype,null);
	}
	/**
	 * 根据code或name查看有无重复数据
	 * @param code,name
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<DicHosptype> getHospTypeBy(String key,String value,String hospTypeId) {
		StringBuffer sql = new StringBuffer();
		sql.append("select * from dic_hosptype where ")
		   .append(key)
		   .append(" = ? and  hosp_type_id <> ? ");
		Query query = getSession().createSQLQuery(sql.toString());
		query.setParameter(0, value);
		query.setParameter(1,hospTypeId);
		return query.list();
	}
	
	/**
	 * 根据条件获取不分页数据
	 * @param page
	 * @return page
	 */
	@Override
	public Pagination getDicHospTypeNoPage(Pagination page){
		String hospTypeCode = page.getConditions().get("hospTypeCode");
		String hospType = page.getConditions().get("hospType");
		String status = page.getConditions().get("status");
		StringBuffer sql = new StringBuffer();
		sql.append(" SELECT * FROM       (SELECT                                      ")
		   .append(" a.hosp_type_code fatherHospTypeCode,                             ")
		   .append(" a.hosp_type fatherHospType,b.hosp_type_code hospTypeCode,        ")
		   .append(" b.hosp_type hospType,						                      ")
		   .append(" case b.status when '0' then '停用' else '启用' end status	      ")
		   .append(" FROM dic_hosptype a                                         	  ")
		   .append(" INNER JOIN dic_hosptype b  ON b.father_id=a.hosp_type_id         ")
		   .append(" WHERE a.father_id = '0'										  ")
		   .append(" UNION															  ")
		   .append(" SELECT hosp_type_code fatherHospTypeCode,                        ")
		   .append(" hosp_type fatherHospType,NULL hospTypeCode,NULL hospType,        ")
		   .append(" case status when '0' then '停用' else '启用' end status          ")
		   .append(" FROM dic_hosptype WHERE father_id = '0')t WHERE 1=1			  ");
		Map<String,Object> params = new HashMap<String, Object>();
		if(StringUtils.isNotBlank(hospTypeCode)){
			sql.append(" and (t.fatherHospTypeCode = :hospTypeCode or t.hospTypeCode = :hospTypeCode ) ");
			params.put("hospTypeCode", hospTypeCode);
		}
		if(StringUtils.isNotBlank(hospType)){
			sql.append(" and (t.fatherHospType like :hospType or t.hospType like :hospType ) ");
			params.put("hospType", "%"+hospType+"%");
		}
		if (StringUtils.isNotBlank(status)) {
			sql.append(" and (t.status = :status )");
			params.put("status", "0".equals(status)?"停用":"启用");
		}
		sql.append(" ORDER BY t.fatherHospTypeCode,t.hospTypeCode ");
		
		page.setRows(dao.getSqlMapList(sql.toString(), params));
		return page;
	}

	
}